#include "../common/Common.h"
#include "SceneTester.h"

void SceneTester::Init()
{
	// Load parameters
	_params.Init("parameters.txt");

	// Load scenes
	LoadScenes("scenesList.txt", _params);
	
	// Default scene to render
	_currentSceneId = 1;
	_currentModelIndex = 1;

	std::cout << "Initialization done\n";

    std::cout << "\n[W/A/S/D/R/F]: Translate camera\n";
    std::cout << "[2/4/6/8]: Look around\n";
    std::cout << "[Left mouse drag]: Look around\n";
    std::cout << "[Right mouse drag]: Pan camera\n";

	std::cout << "[Y]: Take a screenshot & go to the next model\n";
}

void SceneTester::LoadScenes(const string &filename, CommonSceneParameters &params)
{
	int sceneId = 0;

	// The "3" isn't really necessary (any number over "0" is fine)
    std::vector<std::string> fileLines = Utility::GetFileLines(filename, 3);

	auto lineIterator = fileLines.begin();
	while (lineIterator != fileLines.end()) {
		if(DEBUG) cout << "Processing line: " << *lineIterator << endl;
		if (*lineIterator == "") {
			break;
		}

		sceneId++;
        string currentSceneName = *lineIterator;
		if(DEBUG) cout << "Scene filename: " << currentSceneName << endl;

		// Load the entire scene (with original models and such)
		Scene currentScene;
		currentScene.Load(params.databaseDirectory, currentSceneName);

		// Set camera position
		cout << "Setting camera position..." << endl;
		currentScene.TargetCamera(0);

		// Save the scene for later use when we replace the models
		_sceneData.addScene(sceneId, currentScene);
		currentSceneName = currentSceneName.substr(0, currentSceneName.size() - 4);
		_idToSceneName.insert(pair<int, string>(sceneId, currentSceneName));

		lineIterator++;

	} // while() not eof

	_numScenes = sceneId;
}

Scene& SceneTester::GetScene(int sceneId) {
	if (_idToSceneName.count(sceneId) > 0) {
		// The id is present in the map

		return _sceneData.getScene(sceneId);
	}
	else {
		cout << "SceneId " << sceneId << " not found in map!" << endl;
		getchar();
		exit(5);
	}
}

void SceneTester::ReSize(int windowWidth, int windowHeight)
{
	GetScene(_currentSceneId).ReSize(windowWidth, windowHeight);
}

void SceneTester::Update(float seconds)
{
    GetScene(_currentSceneId).Update(seconds);
}

void SceneTester::MouseDown(int button, int x, int y)
{
	GetScene(_currentSceneId).MouseDown(button, x, y);
}

void SceneTester::MouseMove(int x, int y)
{
	GetScene(_currentSceneId).MouseMove(x, y);
}

string SceneTester::GetSceneName(int sceneId)
{
	return _idToSceneName.find(sceneId)->second;
}

string SceneTester::GetScreenshotName() {
	string screenshotName = _params.outputDirectory;
	if (DEBUG) {
		cout << "Current scene index: " << _currentSceneId << endl;
		cout << "Scene name is: " << GetSceneName(_currentSceneId) << endl;
		cout << "Current model index: " << _currentModelIndex << endl;
	}

	string sceneName = GetSceneName(_currentSceneId);
	screenshotName.append(sceneName);
	screenshotName.append("_");

	// Convert model index (an int) to string
	char buffer[65];
	_itoa(_currentModelIndex, buffer, 10);

	screenshotName.append(buffer);
	screenshotName.append(".jpg");

	return screenshotName;
}

void SceneTester::KeyPress(unsigned char key)
{
	string screenshotName;
	if (key != 'y') {
		GetScene(_currentSceneId).KeyPress(key, screenshotName);
	}
	else {
		if (DEBUG) {
			cout << "Current scene index: " << _currentSceneId << endl;
			cout << "Current model index: " << _currentModelIndex << endl;
			cout << "NumScenes: " << _numScenes << endl;
		}
		if (_currentSceneId <= _numScenes) {
			screenshotName = GetScreenshotName();

			if (DEBUG) cout << "Taking Screenshot." << endl;
			GetScene(_currentSceneId).KeyPress(key, screenshotName);

			cout << "Going to next model..." << endl;
			_currentModelIndex++;
			if (_currentModelIndex < GetScene(_currentSceneId).GetNumModelsInScene()) {
				GetScene(_currentSceneId).TargetCamera(_currentModelIndex);
			}
			else {
				// Ran out of models
				cout << "No more models in scene." << endl;
				cout << "Going to next scene." << endl;

				_currentSceneId++;
				if (_currentSceneId > _numScenes) {
					cout << "Finished all scenes... (press any key)" << endl;
					//getchar();
					exit(1);
				}

				// Reset model index
				_currentModelIndex = 1;

				//Scene nextScene = GetScene(_currentSceneId);
				//cout << "Next scene name: " << nextScene.GetSceneName() << endl;
				//vector<ModelInstance*> allmodels = nextScene.GetAllModels();
				//cout << "# models in this scene: " << allmodels.size() << endl;

				GetScene(_currentSceneId).TargetCamera(_currentModelIndex);
				GetScene(_currentSceneId).Render();
				//glFlush();
				glutPostRedisplay();
			}
		}

		//// One check to see if we went past the number of scenes
		//if (_currentSceneId > _numScenes) {
		//	cout << "Finished all scenes... (press any key)" << endl;
		//	getchar();
		//	exit(1);
		//}
	}
}

void SceneTester::Render()
{
	GetScene(_currentSceneId).Render();
}
